package com.glsc.ngateway.platform.service.costallocation;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.glsc.ngateway.common.api.common.dto.PageDataResult;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrDeptDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrEmpDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrEmpSearchDto;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.ldap.resp.LdapResponse;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.api.shortmsg.bo.MessageGenericVo;
import com.glsc.ngateway.common.api.shortmsg.feign.IFeignShortmsgService;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.SystemConfig;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItCloudDevice;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItServerDevice;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItVirtualDevice;
import com.glsc.ngateway.common.base.domain.mysql.gateway.system.SystemMain;
import com.glsc.ngateway.common.base.enums.OaHrmresourceStatusEnum;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.it.ItCloudDeviceRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.it.ItServerDeviceRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.it.ItVirtualDeviceRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.system.SystemMainRepository;
import com.glsc.ngateway.platform.aspect.UserCache;
import com.glsc.ngateway.platform.domain.costallocation.*;
import com.glsc.ngateway.platform.dto.AllDepDto;
import com.glsc.ngateway.platform.dto.BusiSystemInfoDto;
import com.glsc.ngateway.platform.dto.BusiSystemInfoQueryDto;
import com.glsc.ngateway.platform.dto.DepartmentDto;
import com.glsc.ngateway.platform.repo.costallocation.*;
import com.glsc.ngateway.platform.service.SystemConfigService;
import com.glsc.ngateway.platform.service.UserService;
import com.glsc.ngateway.platform.utils.RequestTool;
import com.glsc.ngateway.platform.utils.SpecificationUtil;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.Collator;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.glsc.ngateway.common.api.common.enums.Constant.COSTALLOCATION_BUSISYSTEMINFO_ADMIN;
import static com.glsc.ngateway.common.api.common.enums.Constant.COSTALLOCATION_SYSTEMCOMPONENTCATEGORY_ADMIN;

/**
 * @author guoj
 * @description: 业务系统
 * @date 2024/7/19 9:46
 */
@Service
public class BusiSystemInfoService {
    private static Logger logger = LoggerFactory.getLogger(BusiSystemInfoService.class);
    @Resource
    IFeignLdapService feignLdapService;
    @Autowired
    private IpDetailInfoRepo ipDetailInfoRepo;
    @Resource
    private BusiSystemInfoRepo busiSystemInfoRepo;
    @Resource
    private DepCostAllocationService depCostAllocationService;
    @Resource
    private HisBusiSystemInfoRepo hisbusiSystemInfoRepo;
    @Resource
    private RequestTool requestTool;
    @Resource
    private DepCostAllocationRepo depCostAllocationRepo;
    @Resource
    private HisDepCostAllocationRepo hisdepCostAllocationRepo;
    @Autowired
    private UserCache userCache;
    @Resource
    private UserService userService;
    @Autowired
    private SystemComponentCategoryRepo systemComponentCategoryRepo;
    @Autowired
    private ItVirtualDeviceRepo itVirtualDeviceRepo;
    @Autowired
    private HttpServletRequest request;
    //临时放置  Constant编译十分钟
    @Autowired
    private ItServerDeviceRepo itServerDeviceRepo;
    @Resource
    private SystemConfigService configService;
    @Resource
    private IFeignShortmsgService shortmsgService;
    @Resource
    private SystemMainRepository systemMainRepository;
    @Autowired
    private ItCloudDeviceRepo itCloudDeviceRepo;
    @Autowired
    private IpInfoService ipInfoService;
    @Autowired
    private HisIpInfoService hisIpInfoService;
    @Autowired
    private IpInfoRepo ipInfoRepo;

    /**
     * 新增系统信息
     * @param systemClassNo 业务系统编号
     * @param userAccount 用户oa账户 guoj
     */
    public void synchronizeBusiInfoAdd(String systemClassNo,String userAccount){
        logger.info("新增同步系统信息，系统编号：{}，oa账户：{}", systemClassNo, userAccount);
        if (StrUtil.isBlank(systemClassNo) ) {
            //这种情况只有页面操作上可能出现
            logger.info("同步系统信息，系统编号和责任人账户都为空，不执行同步系统信息操作");
            return;
        }
        PlatformUserDto user = userCache.get(request);
        String currUserOA = user.getUsername();
        if(StrUtil.isNotBlank(systemClassNo)){
            BusiSystemInfo busiSystemInfo = busiSystemInfoRepo.queryBySystemClassNo(systemClassNo);
            SystemMain systemMain = systemMainRepository.findBySystemClassNo(systemClassNo);
            String systemName = systemClassNo;
            if(Objects.nonNull(systemMain)){
                systemName = systemMain.getOpName();
            }
            //页面新增-数据库里也新增
            if(Objects.isNull(busiSystemInfo)){
                BusiSystemInfo temp = new BusiSystemInfo();
                temp.setSystemUserId(userAccount);
                temp.setSystemClassNo(systemClassNo);
                temp.setOperator(currUserOA);
                temp.setSystemName(systemName);
                busiSystemInfoRepo.save(temp);
                //插入流水 此时没有分摊比例
                HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
                hisBusiSystemInfo.setSystemClassNo(systemClassNo);
                hisBusiSystemInfo.setSystemUserId(userAccount);
                hisBusiSystemInfo.setSystemName(systemName);
                hisBusiSystemInfo.setOperator(currUserOA);
                hisBusiSystemInfo.setChangeSource("IT资产或OA流程");
                hisBusiSystemInfo.setChangeType("01");
                hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
                sendWChatAddBusi(userAccount, systemName);
            }else{//页面新增-数据库里编辑
                String systemUserId = busiSystemInfo.getSystemUserId();
                if(StrUtil.isNotBlank(userAccount)){
                    if (StrUtil.isBlank(systemUserId)) {
                        busiSystemInfo.setSystemUserId(userAccount);
                        busiSystemInfo.setOperator(currUserOA);
                    }else if(!systemUserId.contains(userAccount)){
                        systemUserId = systemUserId +"," +userAccount;
                        busiSystemInfo.setSystemUserId(systemUserId);
                        busiSystemInfo.setOperator(currUserOA);
                    }
                    //保存历史
                    this.saveHisBusiSystemInfo(busiSystemInfo,"IT资产或OA流程","02");
                    busiSystemInfoRepo.save(busiSystemInfo);
                    sendWChatAddBusi(userAccount, systemName);
                }
            }
        }
    }

    /**
     * 插入系统信息 及流水
     * 第一次插入表没有分摊比例
     * @param systemClassNo
     * @param opetator
     * @param systemName
     */
    public void addWithoutCostAlloccation(String systemClassNo,String opetator,String systemName,String changeSource){
        BusiSystemInfo temp = new BusiSystemInfo();
        temp.setSystemClassNo(systemClassNo);
        temp.setOperator(opetator);
        temp.setSystemName(systemName);
        busiSystemInfoRepo.save(temp);
        //插入流水 此时没有分摊比例
        HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
        hisBusiSystemInfo.setSystemClassNo(systemClassNo);
        hisBusiSystemInfo.setSystemName(systemName);
        hisBusiSystemInfo.setOperator(opetator);
        hisBusiSystemInfo.setChangeSource(changeSource);
        hisBusiSystemInfo.setChangeType("01");
        hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
    }

    /**
     * 若有
     * 移除指定系统信息的指定责任人
     * 没有不处理
     * @param systemClassNo
     * @param userOAAccount
     */
    public void removeSystemUser(String systemClassNo,String userOAAccount,String currUserOA,boolean canRemove){
        logger.info("移除指定系统信息的指定责任人，systemClassNo：{}，userOAAccount：{}，currUserOA：{}，canRemove：{}",
                systemClassNo,userOAAccount,currUserOA,canRemove);
        BusiSystemInfo busiSystemInfo = busiSystemInfoRepo.queryBySystemClassNo(systemClassNo);
        if(Objects.nonNull(busiSystemInfo)){//移除操作
            //移除原有资产里的责任人 若有
            if (StrUtil.isNotBlank(userOAAccount)) {
                String systemUserId = busiSystemInfo.getSystemUserId();

                if(StrUtil.isNotBlank(systemUserId) && systemUserId.contains(userOAAccount) && canRemove){
                    String afterRemoved = removeUserOAAccount(systemUserId, userOAAccount);

                    if(StrUtil.isBlank(afterRemoved)){
                        //删除业务系统数据 此时是最后一条
                        Long id = busiSystemInfo.getId();
                        busiSystemInfoRepo.deleteById(id);
                        BusiSystemInfo temp = new BusiSystemInfo();
                        BeanUtils.copyProperties(busiSystemInfo,temp);
                        temp.setSystemUserId(afterRemoved);
                        saveHisBusiSystemInfo(temp, "IT资产或OA流程", "03");
                        //业务系统的责任人全部为空 表示该业务系统下架
                        // 此时需要给应用详情中所有使用该业务系统责任人发通知，手动修改分摊比例
                        List<String> allOAAccountBySystemNo = ipInfoService.getAllOAAccountBySystemNo(systemClassNo);
                        SystemMain systemMain = systemMainRepository.findBySystemClassNo(systemClassNo);
                        String systemName = systemClassNo;
                        if(Objects.nonNull(systemMain)){
                            systemName = systemMain.getOpName();
                        }
                        sendGroupWChat(allOAAccountBySystemNo,systemName);
                    }else{
                        busiSystemInfo.setSystemUserId(afterRemoved);
                        busiSystemInfo.setOperator(currUserOA);
                        BusiSystemInfo saved = busiSystemInfoRepo.save(busiSystemInfo);
                        saveHisBusiSystemInfo(saved, "IT资产或OA流程", "03");
                    }
                }
            }
        }
    }


    /**
     * 同一个业务系统 切换新旧责任人
     * @param systemClassNo
     * @param systemUserIdNew
     * @param systemUserIdOld
     * @param operator
     * @param canRemove
     */
    public void operatorBusiInfoFromEditITOA(String systemClassNo,String systemUserIdNew,
                                             String systemUserIdOld,String operator,
                                             boolean canRemove){
        logger.info("同步系统信息，系统编号：{}，oa账户：{}", systemClassNo, operator);
        if (StrUtil.isBlank(systemClassNo) ) {
            //这种情况只有页面操作上可能出现
            logger.info("同步系统信息，系统编号为空，不执行同步系统信息操作");
            return;
        }
        BusiSystemInfo busiSystemInfo = busiSystemInfoRepo.queryBySystemClassNo(systemClassNo);
        SystemMain systemMain = systemMainRepository.findBySystemClassNo(systemClassNo);
        String systemName = systemClassNo;
        if(Objects.nonNull(systemMain)){
            systemName = systemMain.getOpName();
        }
        if(Objects.isNull(busiSystemInfo)){//首次新增 没有分摊比例
            firstAddBusiinfo(systemClassNo,systemName,systemUserIdNew,"01",operator);
        }else{
            //虚拟机 和云平台  只需处理责任人变化的情况
            if(!Objects.equals(systemUserIdNew,systemUserIdOld)){
                String systemUserIdSaved = busiSystemInfo.getSystemUserId();
                String currUserOA = editSystemUserOA(systemUserIdSaved, systemUserIdNew, systemUserIdOld,canRemove);
                busiSystemInfo.setSystemUserId(currUserOA);
                busiSystemInfo.setOperator(operator);
                //保存历史
                saveHisBusiSystemInfo(busiSystemInfo,"IT资产或OA流程","02");
                busiSystemInfoRepo.save(busiSystemInfo);
                sendWChatUpdateBusi(systemUserIdNew, systemName, systemUserIdOld, systemName);
            }
        }
    }

    /**
     * 因为系统信息中，业务系统和责任人的关系表示了多个IT资产记录 1:N
     *  因此移除某一责任人 需要在IT资产中没有任何记录
     * @param systemClassNo
     * @param systemUserId
     * @param serverId
     * @param devId
     * @return
     */
    public boolean canRemove(String systemClassNo,String systemUserId,Integer serverId,String devId){
        int count = 0;
        if(Objects.nonNull(serverId)){
            List<ItServerDevice> itServerDevices = itServerDeviceRepo
                    .queryBySystemClassNoAndUserId(systemClassNo, systemUserId, serverId);
            count = count + itServerDevices.size();
        }else{
            List<ItServerDevice> itServerDevices = itServerDeviceRepo
                    .queryBySystemClassNoAndUserIdWithOutID(systemClassNo, systemUserId);
            count = count + itServerDevices.size();
        }

        if(StrUtil.isNotBlank(devId)){
            //云平台
            if(devId.contains("CS-")){
                //排除当前id
                List<ItCloudDevice> itCloudDevices = itCloudDeviceRepo
                        .queryBySystemClassNoAndUserId(systemClassNo, systemUserId, devId);
                count = count + itCloudDevices.size();
            }else{
                //全部资源
                List<ItCloudDevice> itCloudDevices = itCloudDeviceRepo
                        .queryBySystemClassNoAndUserIdWhitOutId(systemClassNo, systemUserId);
                count = count + itCloudDevices.size();
            }

            //虚拟机
            if(devId.contains("VD-")){
                List<ItVirtualDevice> itVirtualDevices = itVirtualDeviceRepo
                        .queryBySystemClassNoAndUserId(systemClassNo, systemUserId, devId);
                count = count + itVirtualDevices.size();
            }else{
                List<ItVirtualDevice> itVirtualDevices = itVirtualDeviceRepo
                        .queryBySystemClassNoAndUserIdWithOutId(systemClassNo, systemUserId);
                count = count + itVirtualDevices.size();
            }
        }else{
            //全部资源
            List<ItCloudDevice> itCloudDevices = itCloudDeviceRepo
                    .queryBySystemClassNoAndUserIdWhitOutId(systemClassNo, systemUserId);
            count = count + itCloudDevices.size();
            List<ItVirtualDevice> itVirtualDevices = itVirtualDeviceRepo
                    .queryBySystemClassNoAndUserIdWithOutId(systemClassNo, systemUserId);
            count = count + itVirtualDevices.size();

        }
        if (count > 0) {
            return false;
        }else {
            return true;
        }
    }

    /**
     * 从系统信息的责任人source中
     * 若有 移除toDelte
     * 若有 拼接toAdd 不重复
     * @param source  aaa,bbb,ccc
     * @param toAdd ddd
     * @param toDelte bbb
     * @return aaa,ccc,ddd
     */
    public String editSystemUserOA(String source,String toAdd,String toDelte,boolean canRemove){
        if(StrUtil.isBlank(source)){
            return toAdd;
        }
        if(StrUtil.isNotBlank(toAdd) && !source.contains(toAdd)){
            source = source + "," + toAdd;
        }
        if(StrUtil.isBlank(toDelte) || !source.contains(toDelte)){
            return source;
        }
        if (canRemove) {
            Set<String> collect = Arrays.stream(source.split(","))
                    .filter(x -> !toDelte.equals(x))
                    .collect(Collectors.toSet());
            return String.join(",", collect);
        }
        return source;

    }


    /**
     * 第一次新增系统信息
     * 没有分摊比例
     * @param systemClassNo
     * @param systemName
     * @param systemUserOA
     * @param operator
     */
    public void firstAddBusiinfo(String systemClassNo,String systemName,
                                 String systemUserOA,String changeType,String operator){
        logger.info("第一次新增系统信息,系统编号：{}",systemClassNo);
        BusiSystemInfo temp = new BusiSystemInfo();
        temp.setSystemUserId(systemUserOA);
        temp.setSystemClassNo(systemClassNo);
        temp.setOperator(operator);
        temp.setSystemName(systemName);
        busiSystemInfoRepo.save(temp);
        //插入流水 此时没有分摊比例
        HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
        hisBusiSystemInfo.setSystemClassNo(systemClassNo);
        hisBusiSystemInfo.setSystemUserId(systemUserOA);
        hisBusiSystemInfo.setSystemName(systemName);
        hisBusiSystemInfo.setOperator(operator);
        hisBusiSystemInfo.setChangeSource("IT资产或OA流程");
        hisBusiSystemInfo.setChangeType(changeType);
        hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
        sendWChatUpdateBusi(systemUserOA, systemName, null, null);
    }

    /**
     * 新增系统信息 及流水
     * @param systemClassNo
     * @param operator
     * @param systemUserId
     */
    public void addBusiInfo(String oldSystemClassNo,String oldUserAccount,String systemClassNo,String systemUserId,String operator){
        BusiSystemInfo busiSystemInfo = busiSystemInfoRepo.queryBySystemClassNo(systemClassNo);
        SystemMain systemMain = systemMainRepository.findBySystemClassNo(systemClassNo);
        String systemNameNew = systemClassNo;
        if(Objects.nonNull(systemMain)){
            systemNameNew = systemMain.getOpName();
        }
        SystemMain systemMainOld = systemMainRepository.findBySystemClassNo(oldSystemClassNo);
        String systemNameOld = oldSystemClassNo;
        if(Objects.nonNull(systemMainOld)){
            systemNameOld = systemMainOld.getOpName();
        }
        if(Objects.isNull(busiSystemInfo)){//新增
            BusiSystemInfo temp = new BusiSystemInfo();
            temp.setSystemUserId(systemUserId);
            temp.setSystemClassNo(systemClassNo);
            temp.setOperator(operator);
            temp.setSystemName(systemNameNew);
            busiSystemInfoRepo.save(temp);
            //插入流水 此时没有分摊比例
            HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
            hisBusiSystemInfo.setSystemClassNo(systemClassNo);
            hisBusiSystemInfo.setSystemUserId(systemUserId);
            hisBusiSystemInfo.setSystemName(systemNameNew);
            hisBusiSystemInfo.setOperator(operator);
            hisBusiSystemInfo.setChangeSource("IT资产或OA流程");
            hisBusiSystemInfo.setChangeType("01");
            hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
            sendWChatUpdateBusi(systemUserId, systemNameNew,oldUserAccount,systemNameOld);
        }else{
            String systemUserIdOld = busiSystemInfo.getSystemUserId();
            if(StrUtil.isNotBlank(systemUserId)){
                if (StrUtil.isBlank(systemUserIdOld)) {
                    busiSystemInfo.setSystemUserId(systemUserId);
                    busiSystemInfo.setOperator(operator);
                }else if(!systemUserIdOld.contains(systemUserId)){
                    systemUserId = systemUserIdOld +"," +systemUserId;
                    busiSystemInfo.setSystemUserId(systemUserId);
                    busiSystemInfo.setOperator(operator);
                }
                //保存历史
                saveHisBusiSystemInfo(busiSystemInfo,"IT资产或OA流程","02");
                busiSystemInfoRepo.save(busiSystemInfo);
                sendWChatUpdateBusi(systemUserId, systemNameNew,oldUserAccount,systemNameOld);
            }
        }
    }

    /**
     * 移除指定名字
     * @param source aaa,ddd,eee
     * @param target ddd
     * @return aaa,eee
     */
    public String removeUserOAAccount(String source,String target){
        if(StrUtil.isBlank(target)){
            return source;
        }
        String[] split = source.split(",");
        Set<String> collect = Arrays.stream(split).filter(x -> !target.equals(x)).collect(Collectors.toSet());
        String afterRemoved = null;
        if (collect.size() > 0) {
            afterRemoved = String.join(",", collect);
        }
        return afterRemoved;
    }

    public void sendWChatUpdateBusi(String newUserName,String newSystemName,String oldUserName,String oldSystemName){
        logger.info("业务系统更新-触发消息-新责任人：{}，新系统：{}，旧责任人：{}，旧系统：{}",newUserName,newSystemName,oldUserName,oldSystemName);
        if(StrUtil.isBlank(newUserName)){
            return;
        }
        List<String> toSend = new ArrayList<>();
        toSend.add(newUserName);
        SystemConfig agentIdConfig = configService.findByCode("WECHAT_GATEWAY_APP_AGENTID");
        MessageGenericVo build = MessageGenericVo.builder()
                .oaUserAccounts(toSend)
                .agentId(agentIdConfig.getConfigValue())
                .textContent("变更-新责任人："+newUserName +
                        ",新业务系统：" + newSystemName +
                        "，旧责任人：" + oldUserName+
                        ",旧业务系统：" + oldSystemName
                        + "，请维护成本分摊管理菜单的相关数据")
                .build();
        String msg = shortmsgService.sendAgentMessageGeneric(build);
        logger.info("业务系统更新-完成消息发送责任人消息：{}",msg);
    }

    public void sendWChatAddBusi(String userName,String systemClassName){
        logger.info("业务系统新增-触发发送责任人消息：{}，系统名称：{}",userName,systemClassName);
        if(StrUtil.isBlank(userName)){
            return;
        }
        List<String> toSend = new ArrayList<>();
        toSend.add(userName);
        SystemConfig agentIdConfig = configService.findByCode("WECHAT_GATEWAY_APP_AGENTID");
        MessageGenericVo build = MessageGenericVo.builder()
                .oaUserAccounts(toSend)
                .agentId(agentIdConfig.getConfigValue())
                .textContent("新增-业务系统：" + systemClassName + "，请维护成本分摊管理菜单的相关数据")
                .build();
        String msg = shortmsgService.sendAgentMessageGeneric(build);
        logger.info("业务系统新增-完成发送责任人消息：{}",msg);
    }

    /**
     * 临时接口 第一次上生产 数据治理前
     * @param userName
     * @param systemClassName
     */

    public void sendWChatTemp(String userName,String systemClassName){
        logger.info("发送责任人消息：{}，系统名称：{}",userName,systemClassName);
        if(StrUtil.isBlank(userName)){
            return;
        }
        List<String> toSend = new ArrayList<>();
        toSend.add("guoj");
        toSend.add("shilf");
        toSend.add("quanjx");
        SystemConfig agentIdConfig = configService.findByCode("WECHAT_GATEWAY_APP_AGENTID");
        MessageGenericVo build = MessageGenericVo.builder()
                .oaUserAccounts(toSend)
                .agentId(agentIdConfig.getConfigValue())
                .textContent("数据治理前-参数1："+userName +"，参数2：" + systemClassName )
                .build();
        String msg = shortmsgService.sendAgentMessageGeneric(build);
        logger.info("完成发送责任人消息：{}",msg);
    }

    public void sendGroupWChat(List<String> userNames,String systemClassName){
        if(CollectionUtil.isEmpty(userNames)){
            return;
        }
      logger.info("给一组责任人发消息：{}，系统名称：{}",userNames.size(),systemClassName);
        SystemConfig agentIdConfig = configService.findByCode("WECHAT_GATEWAY_APP_AGENTID");
        MessageGenericVo build = MessageGenericVo.builder()
                .oaUserAccounts(userNames)
                .agentId(agentIdConfig.getConfigValue())
                .textContent("业务系统：" + systemClassName + "已下架，请维护系统组件管理数据！")
                .build();
        String msg = shortmsgService.sendAgentMessageGeneric(build);
        logger.info("给一组责任人-完成发送责任人消息：{}",msg);
    }

    /**
     * 后端保存历史
     * @param saved
     */
    public void saveHisBusiSystemInfo(BusiSystemInfo saved,String changeSource,String changeType){
        HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
        BeanUtils.copyProperties(saved,hisBusiSystemInfo);
        hisBusiSystemInfo.setId(null);
        hisBusiSystemInfo.setCreateTime(null);
        hisBusiSystemInfo.setChangeSource(changeSource);
        hisBusiSystemInfo.setChangeType(changeType);
        HisBusiSystemInfo hisSaved = hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
        List<DepCostAllocation> depCostAllocations = depCostAllocationRepo.queryBySystemInfoId(saved.getId());
        List<HisDepCostAllocation> toSave = new ArrayList<>();
        for(DepCostAllocation dca : depCostAllocations){
            HisDepCostAllocation temp = new HisDepCostAllocation();
            dca.setUpdateTime(null);
            BeanUtils.copyProperties(dca,temp);
            temp.setId(null);
            temp.setSystemInfoId(hisSaved.getId());
            toSave.add(temp);
        }
        hisdepCostAllocationRepo.saveAll(toSave);
    }


    /**
     * 删除操作
     * 同步操作包括 1）新增 2）编辑 3）oa流程
     * @param toDeleteId
     */
    public void syncItServerDeviceDelete(String toDeleteId) {
        logger.info("开始同步删除系统信息数据---{}", toDeleteId);
        if (StrUtil.isBlank(toDeleteId)) {
            return;
        }
        if (toDeleteId.contains("VD")) {//虚拟机
            ItVirtualDevice byDevId = itVirtualDeviceRepo.findByDevId(toDeleteId);
            if(Objects.isNull(byDevId)){
                logger.info("未找到虚拟机数据");
            }else{
                String businessName = byDevId.getBusinessName();
                String userId = byDevId.getUserId();
                boolean canRemove = canRemove(businessName, userId, null, toDeleteId);
                doSyncDelete(businessName, userId,canRemove);
            }
        }else if(toDeleteId.contains("CS")){//云平台
            ItCloudDevice byDevId = itCloudDeviceRepo.findByDevId(toDeleteId);
            if(Objects.isNull(byDevId)){
                logger.info("未找到虚拟机数据");
            }else{
                String businessName = byDevId.getBusinessName();
                String userId = byDevId.getUserId();
                boolean canRemove = canRemove(businessName, userId, null, toDeleteId);
                doSyncDelete(businessName, userId,canRemove);
            }
        }else{//服务器资产
            Integer integerId = Integer.valueOf(toDeleteId);
            ItServerDevice byDevId = itServerDeviceRepo.findByDevId(integerId);
            if(Objects.isNull(byDevId)){
                logger.info("未找到虚拟机数据");
            }else{
                String businessName = byDevId.getBusinessName();
                String userId = byDevId.getUserId();
                boolean canRemove = canRemove(businessName, userId, integerId, null);
                doSyncDelete(businessName, userId,canRemove);
            }
        }
        logger.info("完成同步删除系统信息数据---{}", toDeleteId);
    }

    public void doSyncDelete(String businessName,String userId,boolean canRemove){
        PlatformUserDto user = userCache.get(request);
        String currUserOA = user.getUsername();
        String userAccount = "";
        if( StrUtil.isNotBlank(userId)){
            List<Integer> userIds = new ArrayList<>();
            userIds.add(Integer.valueOf(userId));
            LdapResponse<List<LdapEhrEmpDto>> userList = feignLdapService.getByOaUserIdList(userIds);
            List<LdapEhrEmpDto> data = userList.getData();
            LdapEhrEmpDto ldapEhrEmpDto = data.get(0);
            userAccount = ldapEhrEmpDto.getBadge();
        }
        removeSystemUser(businessName,userAccount,currUserOA,canRemove);
    }




    /**
     * 当服务器资产信息的 业务系统名称  发生变化 同步到BusiSystemInfo表中
     * 当虚拟机资产信息的 业务系统名称 发生变化 同步到BusiSystemInfo表中
     * 当云平台设备信息的 业务系统 发生变化 同步到BusiSystemInfo表中
     * 同步操作包括 1）新增 2）编辑 3）oa流程
     * @param dto
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void synchronizeBusiInfoAddOrUpdate(Object dto,boolean isAdd) {
        logger.info("开始新增编辑同步系统信息，{},isAdd:{}", dto,isAdd);
        if(dto instanceof ItServerDevice){
            ItServerDevice itServerDevice = (ItServerDevice) dto;
            this.syncItServerDevice(itServerDevice);
        }else if(dto instanceof ItCloudDevice){
            ItCloudDevice itCloudDevice = (ItCloudDevice) dto;
            this.syncItCloudDevice(itCloudDevice,isAdd);
        }else if(dto instanceof ItVirtualDevice){
            ItVirtualDevice itVirtualDevice = (ItVirtualDevice) dto;
            this.syncItVirtualDevice(itVirtualDevice,isAdd);
        }else {
            logger.info("新增编辑同步系统信息异常,{}", dto.toString());
        }
    }

    /**
     * 将新增编辑数据向成本分摊同步
     * 包括系统信息、IP信息
     * 涉及 系统名称、IP1、责任人
     * @param itVirtualDevice
     */
    public void syncItVirtualDevice(ItVirtualDevice itVirtualDevice,boolean isAdd){
        //系统编号 oa必填 页面非必填
        String newSystemClassNo = itVirtualDevice.getBusinessName();
        //不同步 虚拟主机系统 动力环境系统
        if("34-0-012".equals(newSystemClassNo) || "33-0-014".equals(newSystemClassNo)){
            return;
        }
        //用户的oa的编号 3456 只有一个     oa必填项
        String userId = itVirtualDevice.getUserId();
        //页面非必填 单选 传递oa账户
        String newUserAccount = itVirtualDevice.getUserAccount();
        //说明来自oa 此时userId必传
        if(StrUtil.isBlank(newUserAccount) && StrUtil.isNotBlank(userId)){
            List<Integer> userIds = new ArrayList<>();
            userIds.add(Integer.valueOf(userId));
            LdapResponse<List<LdapEhrEmpDto>> userList = feignLdapService.getByOaUserIdList(userIds);
            List<LdapEhrEmpDto> data = userList.getData();
            LdapEhrEmpDto ldapEhrEmpDto = data.get(0);
            newUserAccount = ldapEhrEmpDto.getBadge();
        }
        //新增
        if (isAdd){
            //插入系统信息 及流水
            synchronizeBusiInfoAdd(newSystemClassNo,newUserAccount);
            //插入应用详情信息 及流水
        }else{//编辑
            String devId = itVirtualDevice.getDevId();
            ItVirtualDevice oldIVD = itVirtualDeviceRepo.findByDevId(devId);
            String oldSystemClassNo = oldIVD.getBusinessName();
            String oldUserID = oldIVD.getUserId();
            boolean canRemove = canRemove(oldSystemClassNo, oldUserID, null, devId);
            doSync(oldUserID, oldSystemClassNo, newSystemClassNo, newUserAccount,canRemove);
        }
    }


    /**
     * 将新增编辑数据向成本分摊同步
     * 包括系统信息、IP信息
     * 涉及 系统名称、IP1、责任人
     * @param itCloudDevice
     */
    public void syncItCloudDevice(ItCloudDevice itCloudDevice,boolean isAdd){
        //系统编号 oa必填 页面非必填
        String newSystemClassNo = itCloudDevice.getBusinessName();
        //不同步 虚拟主机系统 动力环境系统
        if("34-0-012".equals(newSystemClassNo) || "33-0-014".equals(newSystemClassNo)){
            return;
        }
        //用户的oa的编号 3456 只有一个     oa必填项
        String userId = itCloudDevice.getUserId();
        //页面非必填 单选 传递oa账户
        String newUserAccount = itCloudDevice.getUserAccount();
        //说明来自oa 此时userId必传
        if(StrUtil.isBlank(newUserAccount) && StrUtil.isNotBlank(userId)){
            List<Integer> userIds = new ArrayList<>();
            userIds.add(Integer.valueOf(userId));
            LdapResponse<List<LdapEhrEmpDto>> userList = feignLdapService.getByOaUserIdList(userIds);
            List<LdapEhrEmpDto> data = userList.getData();
            LdapEhrEmpDto ldapEhrEmpDto = data.get(0);
            newUserAccount = ldapEhrEmpDto.getBadge();
        }
        //新增
        if (isAdd){
            //插入系统信息 及流水
            synchronizeBusiInfoAdd(newSystemClassNo,newUserAccount);
            //插入应用详情信息 及流水
        }else{//编辑
            String devId = itCloudDevice.getDevId();
            ItCloudDevice oldICD = itCloudDeviceRepo.findByDevId(devId);
            String oldSystemClassNo = oldICD.getBusinessName();
            String oldUserID = oldICD.getUserId();
            boolean canRemove = canRemove(oldSystemClassNo, oldUserID, null, devId);
            doSync(oldUserID, oldSystemClassNo, newSystemClassNo, newUserAccount,canRemove);
        }
    }

    /**
     * 执行同步操作
     * @param oldUserID
     * @param oldSystemClassNo
     * @param newSystemClassNo
     * @param newUserAccount
     */
    public void doSync(String oldUserID,String oldSystemClassNo,
                       String newSystemClassNo,String newUserAccount,
                       boolean canRemove ){
        PlatformUserDto user = userCache.get(request);
        String currUserOA = user.getUsername();
        String oldUserAccount =ipInfoService.getOAaccountByUserId(oldUserID);

        //比较IT在编辑前后的 业务系统不变
        if (Objects.equals(oldSystemClassNo, newSystemClassNo)) {
            operatorBusiInfoFromEditITOA(newSystemClassNo,newUserAccount,oldUserAccount,currUserOA,canRemove);
        }else{
            //业务系统发生变化  移除旧系统的关联  根据状态新增新的关联
            removeSystemUser(oldSystemClassNo,oldUserAccount,currUserOA,canRemove);
            addBusiInfo(oldSystemClassNo,oldUserAccount,newSystemClassNo,newUserAccount,currUserOA);
        }
    }


    /**
     * 将新增编辑数据向成本分摊同步
     * 包括系统信息、IP信息
     * 涉及 系统名称、IP1、责任人
     * @param itServerDevice
     */
    public void syncItServerDevice(ItServerDevice itServerDevice){
        //页面|oa 都是是必填项
        String ip1 = itServerDevice.getIp1();
        //系统编号 oa必填 页面非必填
        String newSystemClassNo = itServerDevice.getBusinessName();
        //不同步 虚拟主机系统 动力环境系统
        if("34-0-012".equals(newSystemClassNo) || "33-0-014".equals(newSystemClassNo)){
            return;
        }
        //用户的oa的编号 3456 只有一个     oa必填项
        String userId = itServerDevice.getUserId();
        //页面非必填 单选 传递oa账户
        String newUserAccount = itServerDevice.getUserAccount();
        //说明来自oa 此时userId必传
        if(StrUtil.isBlank(newUserAccount) && StrUtil.isNotBlank(userId)){
            newUserAccount = ipInfoService.getOAaccountByUserId(userId);
        }
        //新增
        Integer devId = itServerDevice.getDevId();
        if (devId == null){
            //插入系统信息 及流水
            synchronizeBusiInfoAdd(newSystemClassNo,newUserAccount);
            //插入应用详情信息 及流水
        }else{//编辑
            PlatformUserDto user = userCache.get(request);
            String currUserOA = user.getUsername();
            ItServerDevice oldISD = itServerDeviceRepo.findByDevId(devId);
            String oldSystemClassNo = oldISD.getBusinessName();
            String oldUserID = oldISD.getUserId();
            String oldUserAccount = ipInfoService.getOAaccountByUserId(oldUserID);
            //oa流程|页面 都是 非必填项
            String newMachineStatus = itServerDevice.getMachineStatus();
            String oldMachineStatus = oldISD.getMachineStatus();
            boolean canRemove = canRemove(newSystemClassNo, oldUserID, devId, null);

            //比较IT在编辑前后的 业务系统不变
            if (Objects.equals(oldSystemClassNo, newSystemClassNo)) {
                //  状态【在线、冷备、空】则删除旧责任 新增系统或新责任人
                //未考虑状态变化
                if(StrUtil.isBlank(newMachineStatus)
                        || "15".equals(newMachineStatus)
                        || "18".equals(newMachineStatus)){
                    //移除旧责任人 添加新责任人 保存流水
                    operatorBusiInfoFromEditITOAITserver(newSystemClassNo,newUserAccount,
                            oldUserAccount,currUserOA,canRemove,oldMachineStatus);
                }
                //  状态【下架】 删除系统的新责任人【如果有】
                if("116".equals(newMachineStatus)){
                    removeSystemUser(newSystemClassNo,newUserAccount,currUserOA,canRemove);
                }
            }else{
                boolean canRemoveOld = canRemove(oldSystemClassNo, oldUserID, devId, null);
                //业务系统发生变化  移除旧系统的关联  根据状态新增新的关联
                removeSystemUser(oldSystemClassNo,oldUserAccount,currUserOA,canRemoveOld);
                if(StrUtil.isBlank(newMachineStatus)
                        || "15".equals(newMachineStatus)
                        || "18".equals(newMachineStatus)){
                    addBusiInfo(oldSystemClassNo,oldUserAccount,newSystemClassNo,newUserAccount,currUserOA);
                }
                if("116".equals(newMachineStatus)){
                    removeSystemUser(newSystemClassNo,newUserAccount,currUserOA,canRemove);
                }
            }
        }
    }

    public void operatorBusiInfoFromEditITOAITserver(String systemClassNo,String systemUserIdNew,
                                             String systemUserIdOld,String operator,
                                             boolean canRemove,String oldMachineStatus){
        logger.info("同步系统信息，系统编号：{}，oa账户：{}", systemClassNo, operator);
        if (StrUtil.isBlank(systemClassNo) ) {
            //这种情况只有页面操作上可能出现
            logger.info("同步系统信息，系统编号为空，不执行同步系统信息操作");
            return;
        }
        BusiSystemInfo busiSystemInfo = busiSystemInfoRepo.queryBySystemClassNo(systemClassNo);
        SystemMain systemMain = systemMainRepository.findBySystemClassNo(systemClassNo);
        String systemName = systemClassNo;
        if(Objects.nonNull(systemMain)){
            systemName = systemMain.getOpName();
        }
        if(Objects.isNull(busiSystemInfo)){//首次新增 没有分摊比例
            firstAddBusiinfo(systemClassNo,systemName,systemUserIdNew,"01",operator);
        }else{
            String systemUserIdSaved = busiSystemInfo.getSystemUserId();
            //责任人未变化
            if(Objects.equals(systemUserIdNew,systemUserIdOld)){
                //状态变化才操作， 即老状态为非上架状态
                if(!(StrUtil.isBlank(oldMachineStatus)
                        || "15".equals(oldMachineStatus)
                        || "18".equals(oldMachineStatus))){
                    if(StrUtil.isBlank(systemUserIdSaved)){
                        busiSystemInfo.setSystemUserId(systemUserIdNew);
                    }else{
                        if(!systemUserIdSaved.contains(systemUserIdNew)){
                            systemUserIdSaved = systemUserIdSaved +"," +systemUserIdNew;
                            busiSystemInfo.setSystemUserId(systemUserIdSaved);
                        }
                    }
                    busiSystemInfo.setOperator(operator);
                    //保存历史
                    saveHisBusiSystemInfo(busiSystemInfo,"IT资产或OA流程","02");
                    busiSystemInfoRepo.save(busiSystemInfo);
                    sendWChatUpdateBusi(systemUserIdNew, systemName,systemUserIdNew, systemName);
                }
            }else{
                //不是一个责任人
                String currUserOA = editSystemUserOA(systemUserIdSaved, systemUserIdNew, systemUserIdOld,canRemove);
                busiSystemInfo.setSystemUserId(currUserOA);
                busiSystemInfo.setOperator(operator);
                //保存历史
                saveHisBusiSystemInfo(busiSystemInfo,"IT资产或OA流程","02");
                busiSystemInfoRepo.save(busiSystemInfo);
                sendWChatUpdateBusi(systemUserIdNew, systemName,systemUserIdOld,systemName);
            }
        }
    }



    /**
     * 新建应用类别 -查询当前用户可选系统名称
     * @return
     */
    public List<BusiSystemInfo> findByCurrUser(){
        Map<String, Object> param = new HashMap<>();
        PlatformUserDto user = userCache.get(request);
        Set<String> roleNames = new HashSet<>(user.getRoles());
        if (!"itadmin".equals(user.getUsername())
                && !roleNames.contains("itadmin")
                && !roleNames.contains(COSTALLOCATION_BUSISYSTEMINFO_ADMIN)){
            param.put("LIKE_systemUserId",user.getUsername());
        }
        List<BusiSystemInfo> content = busiSystemInfoRepo.findAll(SpecificationUtil.buildSpecification(param, BusiSystemInfo.class));
        return content;
    }


    public Page<BusiSystemInfo> findPage(BusiSystemInfoQueryDto busiSystemInfoQueryDto) {

        logger.info("开始查询系统信息：{}", busiSystemInfoQueryDto.toString());
        String pageSizeQuery = busiSystemInfoQueryDto.getPageSize();
        String pageNoQuery = busiSystemInfoQueryDto.getPageNo();
        Integer pageNo = Objects.nonNull(pageNoQuery) ? Integer.parseInt(pageNoQuery) : null;
        Integer pageSize = Objects.nonNull(pageSizeQuery) ? Integer.parseInt(pageSizeQuery) : null;
        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "id";
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);

        Map<String, Object> param = new HashMap<>();

        PlatformUserDto user = userCache.get(request);
        Set<String> roleNames = new HashSet<>(user.getRoles());
        //个人数据 否则全部数据
        if (!"itadmin".equals(user.getUsername())
                && !roleNames.contains("itadmin")
                && !roleNames.contains(COSTALLOCATION_BUSISYSTEMINFO_ADMIN)){
            param.put("LIKE_systemUserId",user.getUsername());
        }

        String systemClass = busiSystemInfoQueryDto.getSystemClass();
        if (StrUtil.isNotEmpty(systemClass)) {
            param.put("EQ_systemClass", systemClass);
        }
        String mainClass = busiSystemInfoQueryDto.getMainClass();
        if (StrUtil.isNotEmpty(mainClass)) {
            param.put("EQ_mainClass", mainClass);
        }
        String systemClassNo = busiSystemInfoQueryDto.getSystemClassNo();
        if (StrUtil.isNotEmpty(systemClassNo)) {
            param.put("EQ_systemClassNo", systemClassNo);
        }
        Map<String, Object> paramCostAllocation = new HashMap<>();
        String depGradeOneId = busiSystemInfoQueryDto.getDepGradeOneId();
        if (StrUtil.isNotEmpty(depGradeOneId)) {
            paramCostAllocation.put("EQ_depGradeOneId", depGradeOneId);
        }
        String depGradeTwoId = busiSystemInfoQueryDto.getDepGradeTwoId();
        if (StrUtil.isNotEmpty(depGradeTwoId)) {
            paramCostAllocation.put("EQ_depGradeTwoId", depGradeTwoId);
        }
        String depLeader = busiSystemInfoQueryDto.getDepLeader();
        if (StrUtil.isNotEmpty(depLeader)) {
            paramCostAllocation.put("EQ_depLeader", depLeader);
        }
        List<BusiSystemInfo> content = busiSystemInfoRepo.findAll(SpecificationUtil.buildSpecification(param, BusiSystemInfo.class));
        if (!"itadmin".equals(user.getUsername())
                && !roleNames.contains("itadmin")
                && !roleNames.contains(COSTALLOCATION_BUSISYSTEMINFO_ADMIN)){
            //避免名字内部包含关系   haoj  shaojx
            content = content.stream().filter(x -> {
                String systemUserId = x.getSystemUserId();
                List<String> strings = Arrays.asList(systemUserId.split(","));
                if (strings.size() > 1) {
                    if (strings.contains(user.getUsername())) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return true;
                }
            }).collect(Collectors.toList());
        }
        //查询责任人
        String systemUserIdQuery = busiSystemInfoQueryDto.getSystemUserId();
        if(StrUtil.isNotEmpty(systemUserIdQuery)){
            content = content.stream().filter(x -> {
                String systemUserId = x.getSystemUserId();
                List<String> strings = Arrays.asList(systemUserId.split(","));
                return strings.contains(systemUserIdQuery);
            }).collect(Collectors.toList());
        }
        List<BusiSystemInfo> resultList = new ArrayList<>();
        if (!content.isEmpty()) {
            Map<String, String> oaAccount2Username = this.getUserAccount(content);
            Set<Long> collect = content.stream().map(BusiSystemInfo::getId).collect(Collectors.toSet());
            Map<Long, List<DepCostAllocation>> systemid2List = depCostAllocationService.queryBySystemIdSet(collect,paramCostAllocation);
            for (BusiSystemInfo temp : content) {
                String systemUserId = temp.getSystemUserId();
                //拼接一个或多个全部责任人
                if(!StrUtil.isEmpty(systemUserId)){
                    if(systemUserId.contains(",")){
                        String[] split = systemUserId.split(",");
                        List<String> oaaccounts = Arrays.asList(split);
                        List<String> userNameList = new ArrayList<>();
                        for(String oaaccount : oaaccounts){
                            String userNameTemp = oaAccount2Username.get(oaaccount);
                            if(StrUtil.isEmpty(userNameTemp)){
                                continue;
                            }
                            userNameList.add(userNameTemp);
                        }
                        temp.setSystemUserName(StringUtils.join(userNameList, ","));
                    }else{
                        temp.setSystemUserName(oaAccount2Username.get(systemUserId));
                    }
                }
                List<DepCostAllocation> depCostAllocationList = systemid2List.get(temp.getId());
                if (depCostAllocationList != null) {
                    temp.setDepCostAllocationList(depCostAllocationList);
                    resultList.add(temp);
                }else{
                    if(paramCostAllocation.size() ==0){
                        temp.setDepCostAllocationList(new ArrayList<>());
                        resultList.add(temp);
                    }
                }
            }
        }
        ArrayList<AllDepDto> allDep = this.getAllDepWithChildren();
        for(BusiSystemInfo item : resultList){
            String specilaDep = item.getSpecilaDep();
            if (StrUtil.isNotBlank(specilaDep)) {
                JSONArray jsonArray = JSON.parseArray(specilaDep);
                //已选中的数据
                List<AllDepDto> allDepDtos = jsonArray.toJavaList(AllDepDto.class);
                List<AllDepDto> uncheckList = new ArrayList<>();
                for(AllDepDto temp : allDep){
                    String key = temp.getKey();
                    //分公司名称
                    if(!specilaDep.contains(key)){
                        uncheckList.add(temp);
                    }
                    List<AllDepDto> children = temp.getChildren();
                    if(CollectionUtil.isNotEmpty(children)){
                        List<AllDepDto> newChild = children.stream()
                                .filter(x-> !specilaDep.contains(x.getKey()))
                                .collect(Collectors.toList());
                        uncheckList.addAll(newChild);
                    }
                }
                item.setAllDepDtoList(allDepDtos);
                item.setUnCheck(uncheckList);
            }
        }
        List<BusiSystemInfo> orderedDesc = resultList.stream().sorted(new Comparator<BusiSystemInfo>() {
            @Override
            public int compare(BusiSystemInfo o1, BusiSystemInfo o2) {
                return o2.getId().compareTo(o1.getId());
            }
        }).collect(Collectors.toList());
        return PageUtil.listConvertToPage(orderedDesc,pageable);
    }

    /**
     * 生成oa账户到姓名
     * @param content
     * @return
     */
    private Map<String,String> getUserAccount(List<BusiSystemInfo> content){
        Set<String> systemUserIdSet = content.stream()
                .filter(x -> Objects.nonNull(x.getSystemUserId()))
                .map(BusiSystemInfo::getSystemUserId)
                .collect(Collectors.toSet());
        List<String> systemUserIdList = new ArrayList<>();
        for (String systemUserIdTemp : systemUserIdSet) {
            if(StrUtil.isEmpty(systemUserIdTemp)){
                continue;
            }
            //多个责任人
            if(systemUserIdTemp.contains(",")){
                String[] split = systemUserIdTemp.split(",");
                systemUserIdList.addAll( Arrays.asList(split));
            }else{
                systemUserIdList.add(systemUserIdTemp);
            }
        }

        List<User> userList = userService.findAllByAccountList(systemUserIdList);
        return userList
                .stream()
                .collect(Collectors.toMap(User::getUsername, User::getName));
    }

    /**
     * 按照一级部门 二级部门 组装数据
     * @return
     */
    public List<LdapEhrDeptDto> convertToDepList(){
        //获取所有部门
        AppEhrResponse<List<LdapEhrDeptDto>> depts = feignLdapService.getAllDept();
        //过滤无效
        depts.setData(depts.getData().stream().filter(u -> !"1".equals(u.getCanceled())).collect(Collectors.toList()));
        List<LdapEhrDeptDto> data = depts.getData();
        if (Objects.isNull(depts) || CollectionUtil.isEmpty(data)) {
            return new ArrayList<>();
        }

        //全部一级部门
        Set<LdapEhrDeptDto> allGradeOneDepSet = data.stream().filter(x -> "一级部门".equals(x.getDepgrade())).collect(Collectors.toSet());
        return new ArrayList<>(allGradeOneDepSet);
    }


    /**
     * 获取公司- 一级部门
     * @return
     */
    public ArrayList<AllDepDto>  getAllDepWithChildren(){
        List<LdapEhrDeptDto> ldapEhrDeptDtos = this.convertToDepList();
        Map<String, List<LdapEhrDeptDto>> comTilte2List = ldapEhrDeptDtos.stream()
                .filter(x -> StrUtil.isNotBlank(x.getComptitle()))
                .collect(Collectors.groupingBy(LdapEhrDeptDto::getComptitle));
        ArrayList<AllDepDto> result = new ArrayList<>();
        for (String title : comTilte2List.keySet()) {
            List<LdapEhrDeptDto> temp = comTilte2List.get(title);
            AllDepDto father = new AllDepDto();
            father.setTitle(title);
            father.setKey(title);
            List<AllDepDto> children = new ArrayList<>();
            for(LdapEhrDeptDto item : temp){
                AllDepDto child = new AllDepDto();
                String dtitle = item.getDtitle();
                child.setTitle(dtitle);
                if (dtitle.contains("/")) {
                    child.setTitle(dtitle.substring(dtitle.indexOf("/") +1));
                }
                child.setKey(title+"#"+item.getDepid());
                children.add(child);
            }
            father.setChildren(children);
            result.add(father);
        }
        return result;
    }




    /**
     * 按照一级部门下的全部人员
     * @return
     */
    public  List<DepartmentDto> getDepartmentOneUsers(){
        //获取所有部门
        AppEhrResponse<List<LdapEhrDeptDto>> depts = feignLdapService.getAllDept();
        //过滤无效
        depts.setData(depts.getData().stream().filter(u -> !"1".equals(u.getCanceled())).collect(Collectors.toList()));
        List<LdapEhrDeptDto> data = depts.getData();
        if (Objects.isNull(depts) || CollectionUtil.isEmpty(data)) {
            return new ArrayList<>();
        }

        //全部一级部门
        Set<LdapEhrDeptDto> allGradeOneDepSet = data.stream()
                .filter(x -> "一级部门".equals(x.getDepgrade()))
                .collect(Collectors.toSet());
        Map<String, Integer> deptitle2Depid = allGradeOneDepSet.stream()
                .filter(x -> Objects.nonNull(x.getDtitle()) && Objects.nonNull(x.getDepid()))
                .collect(Collectors.toMap(x ->x.getComptitle()+x.getDtitle(), LdapEhrDeptDto::getDepid));

        LdapEhrEmpSearchDto ldapEhrEmpSearchDto = new LdapEhrEmpSearchDto();
        LdapResponse<List<LdapEhrEmpDto>> userList = feignLdapService.getUserList(ldapEhrEmpSearchDto);
        List<LdapEhrEmpDto> allUserList = userList.getData();
        Map<Integer, List<LdapEhrEmpDto>> id2Users = new HashMap<>();
        for (String depTitle : deptitle2Depid.keySet()) {
            List<LdapEhrEmpDto> gradeOneAllUser = allUserList.stream().filter(x -> {
                String status = x.getStatus();
                //在职人员
                if(!OaHrmresourceStatusEnum.isAlive(status)){
                    return false;
                }
                LdapEhrDeptDto deptinfo = x.getDeptinfo();
                if(Objects.isNull(deptinfo)){
                    return false;
                }
                String depgrade = deptinfo.getDepgrade();
                String dtitle = deptinfo.getDtitle();
                String comptitle = deptinfo.getComptitle();
                if ("一级部门".equals(depgrade)) {
                    return depTitle.equals( comptitle + dtitle);
                } else if ("二级部门".equals(depgrade) && StrUtil.isNotBlank(dtitle)) {
                    //二级部门名称中 包含一级部门名称
                    String[] split = dtitle.split("/");
                    List<String> strings = Arrays.asList(split);
                    String gradeOneTitle = strings.get(0);
                    return depTitle.equals(comptitle+gradeOneTitle);
                } else {
                    return false;
                }
            }).collect(Collectors.toList());
            id2Users.put(deptitle2Depid.get(depTitle),gradeOneAllUser);
        }

        List<DepartmentDto> result = new ArrayList();
        for(LdapEhrDeptDto temp : allGradeOneDepSet){
            DepartmentDto departmentDto = new DepartmentDto();
            Integer depid = temp.getDepid();
            departmentDto.setDepidOne(depid);
            String dtitle = temp.getDtitle();
            String comptitle = temp.getComptitle();
            if(StrUtil.isNotBlank(dtitle)
                    && StrUtil.isNotBlank(comptitle)) {
                if(dtitle.contains(comptitle)){
                    departmentDto.setDepOnename(dtitle);
                }else{
                    departmentDto.setDepOnename(comptitle + "/" + dtitle);
                }
            }
            departmentDto.setDepOneAllUsers(id2Users.get(depid));
            result.add(departmentDto);
        }
        //中文排序
        Collections.sort(result, new Comparator<DepartmentDto>() {
            @Override
            public int compare(DepartmentDto o1, DepartmentDto o2) {
                Comparator<Object> compare = Collator.getInstance(java.util.Locale.CHINA);
                return compare.compare(o1.getDepOnename(), o2.getDepOnename());
            }
        });
        return result;
    }

    /**
     * 针对oa等全部门分摊的系统 增加一级部门
     * @param result
     * @param allUserList
     * @return
     */
    public List<DepartmentDto> addSpecialDep( List<DepartmentDto> result,List<LdapEhrEmpDto> allUserList){
        PlatformUserDto userFromRequest = requestTool.getUserFromRequest();
        String oaAccount = userFromRequest.getUsername();
        Optional<LdapEhrEmpDto> first = allUserList.stream()
                .filter(x -> Objects.equals(oaAccount, x.getBadge()))
                .findFirst();
        DepartmentDto allDep = new DepartmentDto();
        allDep.setDepOnename("国联证券全部门");
        allDep.setDepidOne(20241101);
        List<LdapEhrEmpDto> depOneAllUsers = new ArrayList<>();
       
        if (first.isPresent()) {
            depOneAllUsers.add(first.get());
        }else{
            LdapEhrEmpDto ldapEhrEmpDto = new LdapEhrEmpDto();
            ldapEhrEmpDto.setBadge(oaAccount);
            ldapEhrEmpDto.setName(oaAccount);
            depOneAllUsers.add(ldapEhrEmpDto);
        }
        allDep.setDepOneAllUsers(depOneAllUsers);
        result.add(0,allDep);
        return result;

    }

    @Transactional
    public void checkBusiSystemInfo4MultipleDep(BusiSystemInfoDto busiSystemInfoDto,BusiSystemInfo saved){
        PlatformUserDto userFromRequest = requestTool.getUserFromRequest();
        List<DepCostAllocation> isExisted = depCostAllocationRepo.queryBySystemInfoId(saved.getId());
        if(CollectionUtil.isNotEmpty(isExisted)){
            throw PlatformException.errorWithOutMail("已使用一级部门分摊方式，不能使用部门勾选方式。");
        }
        String oaAccount = userFromRequest.getUsername();
        //不考虑是否变更 都要更新当前表
        // 后两个参数是oa账户
        String systemUserId = busiSystemInfoDto.getSystemUserId();
        String mainClass = busiSystemInfoDto.getMainClass();
        String systemClass = busiSystemInfoDto.getSystemClass();
        List<AllDepDto> allDepDtoList = busiSystemInfoDto.getAllDepDtoList();
        String jsonString = JSON.toJSONString(allDepDtoList);
        busiSystemInfoRepo.updateSystemUserIdAllDep(saved.getId(),
                systemUserId,
                oaAccount,
                LocalDateTime.now(),
                mainClass,
                systemClass,
                jsonString);

        //插入历史表 现有已保存数据-->同应用详情 保存最新数据
        HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
        hisBusiSystemInfo.setMainClass(mainClass);
        hisBusiSystemInfo.setSystemName(busiSystemInfoDto.getSystemName());
        hisBusiSystemInfo.setOperator(oaAccount);
        hisBusiSystemInfo.setSystemClass(systemClass);
        hisBusiSystemInfo.setSystemClassNo(saved.getSystemClassNo());
        hisBusiSystemInfo.setSystemUserId(systemUserId);
        hisBusiSystemInfo.setChangeSource("系统信息");
        hisBusiSystemInfo.setChangeType("02");
        hisBusiSystemInfo.setSpecilaDep(jsonString);
        HisBusiSystemInfo hisSaved = hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
        syncMainAndSystemClass(busiSystemInfoDto,saved);
    }


    @Transactional
    public void saveCurrentAndHistory(BusiSystemInfoDto busiSystemInfoDto,BusiSystemInfo saved){
        PlatformUserDto userFromRequest = requestTool.getUserFromRequest();
        List<DepCostAllocation> depCostAllocationList = busiSystemInfoDto.getDepCostAllocationList();
        String oaAccount = userFromRequest.getUsername();
        for(DepCostAllocation dca : depCostAllocationList){
            dca.setId(null);
            dca.setSystemInfoId(saved.getId());
            dca.setOperator(oaAccount);
        }
        depCostAllocationService.setGradeOneTwoNameAndLeaderName(depCostAllocationList);
        //不考虑是否变更 都要更新当前表
        // 后两个参数是oa账户
        String systemUserId = busiSystemInfoDto.getSystemUserId();
        String mainClass = busiSystemInfoDto.getMainClass();
        String systemClass = busiSystemInfoDto.getSystemClass();
        busiSystemInfoRepo.updateSystemUserId(saved.getId(),
                systemUserId,
                oaAccount,
                LocalDateTime.now(),
                mainClass,
                systemClass);
        depCostAllocationRepo.deleteBySystemInfoId(saved.getId());
        depCostAllocationRepo.saveAll(depCostAllocationList);

        //插入历史表 现有已保存数据-->同应用详情 保存最新数据
        List<DepCostAllocation> depCostAllocations = depCostAllocationRepo.queryBySystemInfoId(saved.getId());
        HisBusiSystemInfo hisBusiSystemInfo = new HisBusiSystemInfo();
        hisBusiSystemInfo.setMainClass(mainClass);
        hisBusiSystemInfo.setSystemName(busiSystemInfoDto.getSystemName());
        hisBusiSystemInfo.setOperator(oaAccount);
        hisBusiSystemInfo.setSystemClass(systemClass);
        hisBusiSystemInfo.setSystemClassNo(saved.getSystemClassNo());
        hisBusiSystemInfo.setSystemUserId(systemUserId);
        hisBusiSystemInfo.setChangeSource("系统信息");
        hisBusiSystemInfo.setChangeType("02");
        HisBusiSystemInfo hisSaved = hisbusiSystemInfoRepo.save(hisBusiSystemInfo);
        List<HisDepCostAllocation> toSave = new ArrayList<>();
        for(DepCostAllocation dca : depCostAllocations){
            HisDepCostAllocation temp = new HisDepCostAllocation();
            dca.setUpdateTime(null);
            BeanUtils.copyProperties(dca,temp);
            temp.setId(null);
            temp.setSystemInfoId(hisSaved.getId());
            toSave.add(temp);
        }
        hisdepCostAllocationRepo.saveAll(toSave);
        syncMainAndSystemClass(busiSystemInfoDto,saved);
    }

    /**
     * 大小类发生变更，同步
     * 1应用详情中涉及的分摊比例
     * 2插入一条记录
     * @param busiSystemInfoDto
     * @param saved
     */
    public void syncMainAndSystemClass(BusiSystemInfoDto busiSystemInfoDto,BusiSystemInfo saved){
        String newMainClass = busiSystemInfoDto.getMainClass();
        String newSystemClass = busiSystemInfoDto.getSystemClass();
        String oldMainClass = saved.getMainClass();
        String oldSystemClass = saved.getSystemClass();
        //任一个修改就出发变更
        if (StrUtil.equals(oldMainClass, newMainClass) && StrUtil.equals(oldSystemClass, newSystemClass)) {
            return;
        }
        //任一个修改就出发变更
        String systemClassNo = saved.getSystemClassNo();
        List<IpDetailInfo> ipDetailInfoList = ipDetailInfoRepo.queryBySystemClassNo(systemClassNo);
        if(CollectionUtil.isEmpty(ipDetailInfoList)){
            return;
        }
        for(IpDetailInfo temp : ipDetailInfoList){
            temp.setMainClass(newMainClass);
            temp.setSystemClass(newSystemClass);
        }
        ipDetailInfoRepo.saveAllAndFlush(ipDetailInfoList);
        Set<Long> IpInfoIdSet = ipDetailInfoList.stream()
                .map(IpDetailInfo::getIpInfoId)
                .collect(Collectors.toSet());
        List<IpDetailInfo> ipDetailInfoListSaved = ipDetailInfoRepo.queryByIpInfoId(IpInfoIdSet);
        Map<Long, List<IpDetailInfo>> infoId2Detail = ipDetailInfoListSaved.stream()
                .collect(Collectors.groupingBy(IpDetailInfo::getIpInfoId));
        List<IpInfo> ipInfoList = ipInfoRepo.queryByIDS(IpInfoIdSet);
        hisIpInfoService.saveHisIpInfoBatch(ipInfoList,infoId2Detail);
    }



    /**
     * 由于此处数据由it资产导出  其系统所属信息不能修改
     * @param busiSystemInfoDto
     */
    public BusiSystemInfo checkBusiSystemInfo(BusiSystemInfoDto busiSystemInfoDto) {

        logger.info("新增系统信息dto：{}", busiSystemInfoDto.toString());
        BusiSystemInfo saved = checkBusiSystemInfo4MultipleDep(busiSystemInfoDto);
        List<DepCostAllocation> depCostAllocationList = busiSystemInfoDto.getDepCostAllocationList();
        BigDecimal reduce = depCostAllocationList.stream()
                .filter(x -> Objects.nonNull(x.getCostAllocation()))
                .map(DepCostAllocation::getCostAllocation)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (reduce.compareTo(new BigDecimal("100")) != 0) {
            throw PlatformException.error("成本分摊比例要求总和为100%");
        }
        for(DepCostAllocation dca : depCostAllocationList){
            String depGradeOneId = dca.getDepGradeOneId();
            String depLeader = dca.getDepLeader();
            BigDecimal costAllocation = dca.getCostAllocation();
            if(StrUtil.isEmpty(depGradeOneId)
                    ||StrUtil.isEmpty(depLeader)
                    ||costAllocation ==null){
                throw PlatformException.error("【业务对口部门一级】-【业务部门责任人】-【分摊比例】为必填项！");
            }
        }

        List<String> gradeOneList = depCostAllocationList.stream().map(DepCostAllocation::getDepGradeOneId).collect(Collectors.toList());
        //重复的一级部门
        List<String> repeatGradeOne = gradeOneList.stream()
                .collect(Collectors.groupingBy(x -> x, Collectors.counting())).entrySet()
                .stream().filter(x -> x.getValue() > 1)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        if (repeatGradeOne.size() > 0) {
            throw PlatformException.error("【业务对口部门一级】不允许重复！");
        }
        return saved;
    }


    /**
     * 用于全部门保存检查
     * @param busiSystemInfoDto
     */
    public BusiSystemInfo checkBusiSystemInfo4MultipleDep(BusiSystemInfoDto busiSystemInfoDto) {

        logger.info("新增系统信息dto：{}", busiSystemInfoDto.toString());
        List<AllDepDto> allDepDtoList = busiSystemInfoDto.getAllDepDtoList();
        if (CollectionUtil.isEmpty(allDepDtoList)) {
            throw PlatformException.error("请勾选分摊部门");
        }
        long id = busiSystemInfoDto.getId();
        //库中从1开始
        if (id ==0){
            throw PlatformException.error("请传入系统基础信息");
        }
        BusiSystemInfo saved = busiSystemInfoRepo.queryById(id);
        if(!saved.getSystemName().equals(busiSystemInfoDto.getSystemName())){
            throw PlatformException.error("请勿修改系统基础信息");
        }
        String systemClass = busiSystemInfoDto.getSystemClass();
        if(StrUtil.isBlank(systemClass)){
            throw PlatformException.error("系统小类不允许为空");
        }
        String mainClass = busiSystemInfoDto.getMainClass();
        if(StrUtil.isBlank(mainClass)){
            throw PlatformException.error("系统大类不允许为空");
        }
        return saved;
    }

    /**
     * 用于判断是否写入历史表
     * 写：1）旧值包含全部属性【避免临时修改的部分数据】
     * 2)新旧发生变化
     * 1优先级高于2
     * @param saved
     * @return
     */
    public boolean hasChangedAndHasAllfield(BusiSystemInfo saved,
                                            List<DepCostAllocation> newDCA,
                                            List<DepCostAllocation> oldDCA) {
        //旧值没有保存责任人
        if(StrUtil.isEmpty(saved.getSystemUserId())){
            return false;
        }
        //旧值没有成本比例
        if (oldDCA.size() == 0) {
            return false;
        }
        //旧值的成本本分摊列表 任一四项不全 则false
        for(DepCostAllocation dca : oldDCA){
            if(StrUtil.isEmpty(dca.getDepLeader())
                    || StrUtil.isEmpty(dca.getDepGradeOneId())
                    ||dca.getCostAllocation() ==null){
                return false;
            }
        }
        //新旧数量不一致
        if (newDCA.size() != oldDCA.size()) {
            return true;
        }
        //todo
        return true;

    }

    /**
     * 保存应用类型
     * @param toSaveList
     */
    @Transactional
    public void saveSystemComponentCategory(List<SystemComponentCategory> toSaveList) {
        if(CollectionUtil.isEmpty(toSaveList)){
            throw PlatformException.errorWithOutMail("当前为编辑操作，应用类别不允许为空");
        }
        preCheck(toSaveList);
        Long systemInfoId = toSaveList.get(0).getSystemInfoId();
        Set<Long> systemInfoIdSet = new HashSet<>();
        systemInfoIdSet.add(systemInfoId);
        List<SystemComponentCategory> existeds = systemComponentCategoryRepo.queryBySystemInfoId(systemInfoIdSet);
        Set<Long> sccIds = existeds.stream().map(SystemComponentCategory::getId).collect(Collectors.toSet());

        PlatformUserDto user = userCache.get(request);
        Map<Long, SystemComponentCategory> id2Entity = toSaveList.stream()
                .filter(x -> Objects.nonNull(x.getId()))
                .collect(Collectors.toMap(SystemComponentCategory::getId, x -> x));
        List<SystemComponentCategory> result = new ArrayList<>();
        for(SystemComponentCategory toSave : toSaveList){
            Long id = toSave.getId();
            //已有
            if (Objects.nonNull(id)) {
                SystemComponentCategory systemComponentCategory = id2Entity.get(id);
                BeanUtils.copyProperties(toSave,systemComponentCategory);
                systemComponentCategory.setOperator(user.getUsername());
                systemComponentCategory.setCreateTime(LocalDateTime.now());
                result.add(systemComponentCategory);
            }else{
                toSave.setOperator(user.getUsername());
                toSave.setCreateTime(LocalDateTime.now());
                result.add(toSave);
            }
        }

        Set<Long> toSaveId = toSaveList.stream()
                .filter(x -> Objects.nonNull(x.getId()))
                .map(SystemComponentCategory::getId)
                .collect(Collectors.toSet());
        //移除本次保存的 留下全部需要删除的
        sccIds.removeAll(toSaveId);
        //判断待移除的类别是否正在使用
        if (alreadyUsed(sccIds)) {
            throw PlatformException.error("待删除的应用类别正在被使用，请先删除应用详情的应用类别");
        }
        systemComponentCategoryRepo.deleteAllById(sccIds);
        systemComponentCategoryRepo.saveAll(result);
    }

    /**
     * 判断待删除的应用类别是否正在使用
     * @param sccIds
     * @return
     */
    public boolean alreadyUsed(Set<Long> sccIds){
        if(CollectionUtil.isEmpty(sccIds)){
            return false;
        }
        List<IpDetailInfo> ipDetailInfoList = ipDetailInfoRepo.queryByComponentCategoryId(sccIds);
        if(CollectionUtil.isEmpty(ipDetailInfoList)){
            return false;
        }
        return true;
    }

    /**
     * 保存应用类型
     * @param toDeleteList
     */
    public void deleteSystemComponentCategory(List<SystemComponentCategory> toDeleteList) {
        preCheck(toDeleteList);
        Set<Long> collect = toDeleteList.stream()
                .filter(x -> Objects.nonNull(x.getId()))
                .map(SystemComponentCategory::getId)
                .collect(Collectors.toSet());
        if(alreadyUsed(collect)){
            throw PlatformException.error("待删除的应用类别正在被使用，请先删除应用详情的应用类别");
        }
        systemComponentCategoryRepo.deleteAll(toDeleteList);
    }

    /**
     * 保存、更新、删除前的检查
     * @param systemComponentCategorylist
     */
    public void preCheck(List<SystemComponentCategory> systemComponentCategorylist){
        boolean hasNull = systemComponentCategorylist
                .stream()
                .anyMatch(x -> Objects.isNull(x.getSystemInfoId()));
        if(hasNull){
            throw PlatformException.error("所属系统不能为空");
        }
        PlatformUserDto user = userCache.get(request);
        List<BusiSystemInfo> all = busiSystemInfoRepo.findAll();
        Set<Long>  allBsiID = all.stream()
                .map(BusiSystemInfo::getId)
                .collect(Collectors.toSet());
        Set<Long> paramIDSet = systemComponentCategorylist.stream()
                .map(SystemComponentCategory::getSystemInfoId)
                .collect(Collectors.toSet());
        if (paramIDSet.size() != 1) {
            throw PlatformException.error("单次操作只能选择一个所属系统名称");
        }
        Long paramID = new ArrayList<>(paramIDSet).get(0);
        boolean hasSystem = allBsiID.stream().anyMatch(paramID::equals);
        if(!hasSystem){
            throw PlatformException.error("所属系统不存在");
        }
        BusiSystemInfo busiSystemInfo = all.stream().filter(x -> x.getId().equals(paramID)).findFirst().get();
        String systemUserId = busiSystemInfo.getSystemUserId();
        if(StringUtils.isBlank(systemUserId)){
            throw PlatformException.error("未找到所属系统责任人，无法操作！");
        } else if(!systemUserId.contains(user.getUsername())){
            throw PlatformException.error("所属系统责任人不包括当前用户，无法操作！");
        }
        List<String> collect = systemComponentCategorylist.stream().map(SystemComponentCategory::getComponentCategory)
                .collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(collect)){
            Set<String> distinct = new HashSet<>(collect);
            if(distinct.size() != collect.size()){
                throw PlatformException.errorWithOutMail("同一系统下，不允许相同应用类别");
            }
        }


    }

    /**
     * 查询应用类别分页
     * @param busiSystemInfoQueryDto
     * @return
     */
    public Page<BusiSystemInfo> findSCCPage(BusiSystemInfoQueryDto busiSystemInfoQueryDto) {

        logger.info("开始查询系统信息：{}", busiSystemInfoQueryDto.toString());
        String pageSizeQuery = busiSystemInfoQueryDto.getPageSize();
        String pageNoQuery = busiSystemInfoQueryDto.getPageNo();
        Integer pageNo = Objects.nonNull(pageNoQuery) ? Integer.parseInt(pageNoQuery) : null;
        Integer pageSize = Objects.nonNull(pageSizeQuery) ? Integer.parseInt(pageSizeQuery) : null;
        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "id";
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);

        Map<String, Object> param = new HashMap<>();

        PlatformUserDto user = userCache.get(request);
        Set<String> roleNames = new HashSet<>(user.getRoles());
        //个人数据 否则全部数据
        if (!"itadmin".equals(user.getUsername())
                && !roleNames.contains("itadmin")
                && !roleNames.contains(COSTALLOCATION_SYSTEMCOMPONENTCATEGORY_ADMIN)){
            param.put("LIKE_systemUserId",user.getUsername());
        }
        String systemClass = busiSystemInfoQueryDto.getSystemClass();
        if (StrUtil.isNotEmpty(systemClass)) {
            param.put("EQ_systemClass", systemClass);
        }
        String mainClass = busiSystemInfoQueryDto.getMainClass();
        if (StrUtil.isNotEmpty(mainClass)) {
            param.put("EQ_mainClass", mainClass);
        }
        String systemClassNo = busiSystemInfoQueryDto.getSystemClassNo();
        if (StrUtil.isNotEmpty(systemClassNo)) {
            param.put("EQ_systemClassNo", systemClassNo);
        }
        Map<String, Object> paramSystemComponentCategory = new HashMap<>();
        String componentCategory = busiSystemInfoQueryDto.getComponentCategory();
        if (StrUtil.isNotEmpty(componentCategory)) {
            paramSystemComponentCategory.put("EQ_componentCategory", componentCategory);
        }
        String defaultPath = busiSystemInfoQueryDto.getDefaultPath();
        if (StrUtil.isNotEmpty(defaultPath)) {
            paramSystemComponentCategory.put("LIKE_defaultPath", defaultPath);
        }
        List<BusiSystemInfo> content = busiSystemInfoRepo.findAll(SpecificationUtil.buildSpecification(param, BusiSystemInfo.class));
        if (!"itadmin".equals(user.getUsername())
                && !roleNames.contains("itadmin")
                && !roleNames.contains(COSTALLOCATION_SYSTEMCOMPONENTCATEGORY_ADMIN)){
            //避免名字内部包含关系   haoj  shaojx
            content = content.stream().filter(x -> {
                String systemUserId = x.getSystemUserId();
                List<String> strings = Arrays.asList(systemUserId.split(","));
                if (strings.size() > 1) {
                    if (strings.contains(user.getUsername())) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return true;
                }
            }).collect(Collectors.toList());
        }

        //查询责任人
        String systemUserIdQuery = busiSystemInfoQueryDto.getSystemUserId();
        if(StrUtil.isNotEmpty(systemUserIdQuery)){
            content = content.stream().filter(x -> {
                String systemUserId = x.getSystemUserId();
                List<String> strings = Arrays.asList(systemUserId.split(","));
                return strings.contains(systemUserIdQuery);
            }).collect(Collectors.toList());
        }
        Map<String, String> oaAccount2Username = this.getUserAccount(content);
        List<BusiSystemInfo> resultList = new ArrayList<>();
        if (content.size() != 0) {
            Set<Long> collect = content.stream().map(BusiSystemInfo::getId).collect(Collectors.toSet());
            Map<Long, List<SystemComponentCategory>> systemid2List = querySCCBySystemIdSetAndParams(collect,paramSystemComponentCategory);
            for (BusiSystemInfo temp : content) {
                String systemUserId = temp.getSystemUserId();
                //拼接一个或多个全部责任人
                if(!StrUtil.isEmpty(systemUserId)){
                    if(systemUserId.contains(",")){
                        String[] split = systemUserId.split(",");
                        List<String> oaaccounts = Arrays.asList(split);
                        List<String> userNameList = new ArrayList<>();
                        for(String oaaccount : oaaccounts){
                            String userNameTemp = oaAccount2Username.get(oaaccount);
                            if(StrUtil.isEmpty(userNameTemp)){
                                continue;
                            }
                            userNameList.add(userNameTemp);
                        }
                        temp.setSystemUserName(StringUtils.join(userNameList, ","));
                    }else{
                        temp.setSystemUserName(oaAccount2Username.get(systemUserId));
                    }
                }

                List<SystemComponentCategory> systemComponentCategoryList = systemid2List.get(temp.getId());
                if (systemComponentCategoryList != null) {
                    temp.setSystemComponentCategoryList(systemComponentCategoryList);
                    resultList.add(temp);
                }else{
                    if(paramSystemComponentCategory.size() ==0){
                        temp.setSystemComponentCategoryList(new ArrayList<>());
                        resultList.add(temp);
                    }
                }
            }
        }
        return PageUtil.listConvertToPage(resultList,pageable);
    }

    /**
     * 查询应用类别
     * @param systemIdSet
     * @return
     */
    public Map<Long, List<SystemComponentCategory>> querySCCBySystemIdSetAndParams(Set<Long> systemIdSet,Map<String, Object> paramSystemComponentCategory){
        if (systemIdSet == null || systemIdSet.size() == 0) {
            return new HashMap<>();
        }
        List<SystemComponentCategory> toGroup;
        List<SystemComponentCategory> depCostAllocations = systemComponentCategoryRepo.queryBySystemInfoId(systemIdSet);
        if (paramSystemComponentCategory.size() != 0) {
            List<SystemComponentCategory> all = systemComponentCategoryRepo.findAll(SpecificationUtil.buildSpecification(paramSystemComponentCategory, SystemComponentCategory.class));
            if(CollectionUtil.isNotEmpty(all)){
                Set<Long> collect = all.stream().map(SystemComponentCategory::getSystemInfoId).collect(Collectors.toSet());
                //取交集
                systemIdSet.retainAll(collect);
                toGroup = depCostAllocations.stream().filter(x -> systemIdSet.contains(x.getSystemInfoId())).collect(Collectors.toList());
          }else{
            toGroup = new ArrayList<>();
            }
        }else{
            //此时子类无查询字段  按照父类查询
           toGroup = depCostAllocations;
        }
        Map<Long, List<SystemComponentCategory>> systemInfoId2List = toGroup.stream()
                .collect(Collectors.groupingBy(SystemComponentCategory::getSystemInfoId));
        return systemInfoId2List;
    }

    public List<BusiSystemInfo> findAllForSelect() {
        return busiSystemInfoRepo.findAll();
    }
}
